package cn.modoumama.excelUilt.util;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.DataFormat;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.modoumama.excelUilt.common.Common;
import cn.modoumama.excelUilt.po.CellEntity;
import cn.modoumama.excelUilt.po.SheetEntity;

public class ExportExcel {
    public static Logger logger = LoggerFactory.getLogger(ExportExcel.class);

    private ExportExcel() {
        super();
    }
    
    /**
     * 导出Excel<br>
     * <br>  
     * 创建人：邓强   <br>
     * 创建时间：2018年2月10日 下午5:22:22    <br> 
     * 修改人：  <br>
     * 修改时间：2018年2月10日 下午5:22:22   <br>  
     * 修改备注：     <br> 
     * @param sheetEneity
     * @param path
     * @return
     */
    public static Workbook writeExcel(SheetEntity sheetEneity, String path){
		File file = new File(path);
		return writeExcel(sheetEneity, file);
    }
    
    /**
     * 导出Excel<br>
     * <br>  
     * 创建人：邓强   <br>
     * 创建时间：2018年2月10日 下午5:22:46    <br> 
     * 修改人：  <br>
     * 修改时间：2018年2月10日 下午5:22:46   <br>  
     * 修改备注：     <br> 
     * @param sheetEneity
     * @param file
     * @return
     */
    public static Workbook writeExcel(SheetEntity sheetEneity, File file){
    	Workbook workbook=null;
    	OutputStream out = null;
    	try {
			out = new FileOutputStream(file);
			workbook = writeExcel(sheetEneity, out);
		} catch (FileNotFoundException e) {
			logger.error("文件{}未知道",file.getPath());
		}finally{
			if(out != null){
				try {
					out.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return workbook;
    }
    
    /**
     * 导出Excel<br>
     * <br>  
     * 创建人：邓强   <br>
     * 创建时间：2018年2月10日 下午5:22:56    <br> 
     * 修改人：  <br>
     * 修改时间：2018年2月10日 下午5:22:56   <br>  
     * 修改备注：     <br> 
     * @param sheetEntity
     * @param out
     * @return
     */
    public static Workbook writeExcel(SheetEntity sheetEntity, OutputStream out){
    	// 声明一个工作薄
		Workbook workbook = createExcel();
		sheetEntity.setWorkbook(workbook);
		createExcel(workbook, sheetEntity);
		writeExcel(workbook, out);
		return workbook;
    }
    
    /**
     * 导出多页Excel<br>
     * <br>  
     * 创建人：邓强   <br>
     * 创建时间：2018年2月10日 下午5:23:09    <br> 
     * 修改人：  <br>
     * 修改时间：2018年2月10日 下午5:23:09   <br>  
     * 修改备注：     <br> 
     * @param sheetEntitys
     * @param path
     * @return
     */
    public static Workbook writeExcel(List<SheetEntity> sheetEntitys, String path){
		File file = new File(path);
		return writeExcel(sheetEntitys, file);
    }
    
    /**
     * 导出多页Excel<br>
     * <br>  
     * 创建人：邓强   <br>
     * 创建时间：2018年2月10日 下午5:24:24    <br> 
     * 修改人：  <br>
     * 修改时间：2018年2月10日 下午5:24:24   <br>  
     * 修改备注：     <br> 
     * @param sheetEntitys
     * @param file
     * @return
     */
    public static Workbook writeExcel(List<SheetEntity> sheetEntitys, File file){
    	Workbook workbook=null;
    	OutputStream out = null;
    	try {
			out = new FileOutputStream(file);
			workbook = writeExcel(sheetEntitys, out);
		} catch (FileNotFoundException e) {
			logger.error("文件{}未知道",file.getPath());
		}finally{
			if(out != null){
				try {
					out.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return workbook;
    }
    
    /**
     * 导出多页Excel<br>
     * <br>  
     * 创建人：邓强   <br>
     * 创建时间：2018年2月10日 下午5:24:35    <br> 
     * 修改人：  <br>
     * 修改时间：2018年2月10日 下午5:24:35   <br>  
     * 修改备注：     <br> 
     * @param sheetEneitys
     * @param out
     * @return
     */
    public static Workbook writeExcel(List<SheetEntity> sheetEneitys, OutputStream out){
    	// 声明一个工作薄
		Workbook workbook = createExcel();
		for (SheetEntity sheetEntity : sheetEneitys) {
			createExcel(workbook, sheetEntity);
		}
		writeExcel(workbook, out);
		return workbook;
    }

    /**
     * 获取一个Workbook对象<br>
     * <br>  
     * 创建人：邓强   <br>
     * 创建时间：2018年2月10日 上午10:40:35    <br> 
     * 修改人：  <br>
     * 修改时间：2018年2月10日 上午10:40:35   <br>  
     * 修改备注：     <br> 
     * @return
     */
    public static Workbook createExcel(){
    	// 声明一个工作薄
    	return new SXSSFWorkbook();
    }
    
   /**
    * 创建Excel的一页数据<br>
    * <br>  
    * 创建人：邓强   <br>
    * 创建时间：2018年2月10日 下午5:24:51    <br> 
    * 修改人：  <br>
    * 修改时间：2018年2月10日 下午5:24:51   <br>  
    * 修改备注：     <br> 
    * @param workbook
    * @param sheetEntity
    */
    public static void createExcel(Workbook workbook,SheetEntity sheetEntity){
    		try {
    			sheetEntity.setWorkbook(workbook);
    			sheetEntity = sheetEntity.clone();
    			DataFormat dataFormat = workbook.createDataFormat();
				// 生成一个表格
    			Sheet sheet = workbook.getSheet(sheetEntity.getName());
    			if(sheet == null){
    				sheet = workbook.createSheet(sheetEntity.getName());
    			}
				sheet.setDefaultColumnWidth(sheetEntity.getWidth()); 
				sheet.setDefaultRowHeightInPoints(sheetEntity.getHeight());
				List<?> data = sheetEntity.getData();
				if(data!=null && data.size()>0){
					Object obj= data.get(0);
					for (Integer index : sheetEntity.keySet()) {
						//设置默认宽度
						CellEntity cellEntry = sheetEntity.get(index).getValue();
						String fieldName = sheetEntity.get(index).getKey();
						Class<?> clazz = Common.getPropertyType(obj.getClass(), fieldName);
						Integer width = cellEntry.getWidth();
						if(width != null){
							width = width*256;
							sheet.setColumnWidth(index, width);
						}

						CellStyle cellStyle = workbook.createCellStyle();
						
				    	String  format = cellEntry.getFormat();
				    	if(clazz.getName().equals(Date.class.getName()) || Date.class.isAssignableFrom(clazz)){
				    		format = StringUtils.isNotBlank(format) ? format : sheetEntity.getDateFormat();
				    	}
				    	
				    	if(StringUtils.isNotBlank(format)){
				    		short formatIndex = dataFormat.getFormat(format);
				    		cellStyle.setDataFormat(formatIndex);
				    	}
				    	
				    	Font font = cellEntry.getFont();
				    	if(font != null){
				    		cellStyle.setFont(font);
				    	}
				    	
				    	cellStyle.setAlignment(CellStyle.ALIGN_CENTER);
				    	cellStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
				    	
				    	cellEntry.setCellStyle(cellStyle);
					}
				}
				
				Integer lastRowNum = sheet.getLastRowNum();
				if(lastRowNum==0){
					if(sheetEntity.isHead()){
						Row row = sheet.createRow(0);
						sheetEntity.rowHead(row);
						lastRowNum++;
					}
				}
				
				for (int i = 0; i < data.size(); i++) {
					Row row = sheet.createRow(lastRowNum);
					sheetEntity.rowData(row, data.get(i));
					lastRowNum++;
				}
				
				
			}catch (Exception e) {
				e.printStackTrace();
				logger.error(e.getMessage());
			}
    }
    
    /**
     * 把Excel数据写入文件<br>
     * <br>  
     * 创建人：邓强   <br>
     * 创建时间：2018年2月10日 下午5:25:25    <br> 
     * 修改人：  <br>
     * 修改时间：2018年2月10日 下午5:25:25   <br>  
     * 修改备注：     <br> 
     * @param workbook
     * @param path
     */
    public static void writeExcel(Workbook workbook,String path){
    	File file = new File(path);
    	writeExcel(workbook, file);
    }
    
    /**
     * 把Excel数据写入文件<br>
     * <br>  
     * 创建人：邓强   <br>
     * 创建时间：2018年2月10日 下午5:25:48    <br> 
     * 修改人：  <br>
     * 修改时间：2018年2月10日 下午5:25:48   <br>  
     * 修改备注：     <br> 
     * @param workbook
     * @param file
     */
    public static void writeExcel(Workbook workbook,File file){
    	try {
			OutputStream out = new FileOutputStream(file);
			writeExcel(workbook, out);
		} catch (FileNotFoundException e) {
			logger.error("文件{}未找到！",file.getPath());
		}
    }
    
    /**
     * 把Excel数据写入输入流<br>
     * <br>  
     * 创建人：邓强   <br>
     * 创建时间：2018年2月10日 下午5:25:55    <br> 
     * 修改人：  <br>
     * 修改时间：2018年2月10日 下午5:25:55   <br>  
     * 修改备注：     <br> 
     * @param workbook
     * @param out
     */
    public static void writeExcel(Workbook workbook,OutputStream out){
    	try {
    		workbook.write(out);
		} catch (IOException e) {
			logger.error("写入错误");
		}
    }
}
